package assignment.ton.gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.regex.PatternSyntaxException;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import assignment.ton.def.Action;
import assignment.ton.def.Method;
import assignment.ton.def.Parameter;
import assignment.ton.def.Util;
import assignment.ton.gui.interfaces.AddParameterInterface;
/**
 * Creates a frame for editing and creating methods
 * @author Tim
 *
 */
public class EditMethod extends JFrame implements ActionListener, AddParameterInterface{
	private static final long serialVersionUID = 1625538135212650756L;
	private JLabel name, type, method;
	private JButton submit, cancel, add, delete, editCode;
	private JTextField nameField;
	private JComboBox typeBox, parameterBox;
	private Method theMethod;
	private MainFrame mainFrame;
	private MethodFrame methodFrame;
	public EditMethod(MainFrame mF, Method meth, MethodFrame methFrame){
		mainFrame = mF;
		methodFrame = methFrame;
		theMethod = meth; 
		AbstractAction submitAction = new AbstractAction("Submit"){
			private static final long serialVersionUID = 7257370266664900955L;
			public void actionPerformed(ActionEvent e){
				submit();
			}
		};
		this.setTitle("Methods");
		this.addWindowListener(new WindowAdapter(){ //now make it do something more interesting
			public void windowClosing(WindowEvent e){
				quit();
			}
		});
		this.setResizable(false);
		this.setLocationRelativeTo(mainFrame);
		this.setLayout(new GridBagLayout());
		this.setIconImage(new ImageIcon(getClass().getResource("ton_icon.gif")).getImage());
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.insets = new Insets(2,2,2,2);
		name = new JLabel("Name");
		type = new JLabel("Type");
		nameField = new JTextField(20);
		nameField.setAction(submitAction);
		String[] typeArray = Util.getDataTypes();
		String[] voidArray = {"void"};
		typeBox = new JComboBox(Util.mergeStringArrays(voidArray,typeArray));
		c.gridx = 0;
		c.gridy = 0;
		this.add(name, c);
		c.gridx = 1;
		this.add(nameField, c);
		c.gridx = 0;
		c.gridy = 1;
		this.add(type, c);
		c.gridx = 1;
		this.add(typeBox,c);
		//parameter section
		c.gridy = 2;
		c.gridx = 0;
		method = new JLabel("Parameters");
		this.add(method, c);
		c.gridy = 3;
		c.gridx = 0;
		add = new JButton("Add");
		add.addActionListener(this);
		delete = new JButton("Delete");
		delete.addActionListener(this);
		JPanel subPanel = new JPanel();
		this.add(subPanel, c);
		subPanel.add(add);
		subPanel.add(delete);
		c.gridx = 1;
		parameterBox = new JComboBox();
		this.add(parameterBox, c);
		//end param section
		JPanel bottomPanel = new JPanel();
		c.gridx = 0;
		c.gridy = 4;
		c.gridwidth = 2;
		c.fill = GridBagConstraints.NONE;
		this.add(bottomPanel, c);
		submit = new JButton("Submit");
		bottomPanel.add(submit);
		submit.addActionListener(this);
		cancel = new JButton("Cancel");
		bottomPanel.add(cancel);
		cancel.addActionListener(this);
		editCode = new JButton("Edit Extra Code");
		editCode.addActionListener(this);
		bottomPanel.add(editCode);
		//if meth not null
		nameField.setText(meth.getName());
		if(theMethod.getType()!=null){ typeBox.setSelectedItem(meth.getType()); }
		rebuildList();
		pack();
	}
	@Override
	public void actionPerformed(ActionEvent event) {
		String actionCommand = event.getActionCommand();
		if("Cancel".equals(actionCommand)){
			quit();
		}else if("Add".equals(actionCommand)){
			Parameter param = new Parameter(null, null, false);
			AddParameter p = new AddParameter(mainFrame.getSelected(), param, mainFrame, this); 	//Create a new parameter entry dialogue.
			p.setVisible(true);	
		}else if("Delete".equals(actionCommand)){
			deleteParameter();
		}else if("Submit".equals(actionCommand)){
			submit();
		}else if("Edit Extra Code".equals(actionCommand)){
			mainFrame.setAction(Action.EDITCODE);
			CodeEditorFrame cf = new CodeEditorFrame(mainFrame,theMethod,null);
			cf.setVisible(true);
		}
		
	}
	public void deleteParameter(){
		try{
			String theType = (String)parameterBox.getSelectedItem();
			String[] typeArray = theType.split(":");
			theType = typeArray[0];
			theMethod.removeParameter(theType);
			rebuildList();
		}catch(PatternSyntaxException f){
			Util.showError(this, "Quit trying to delete nothing");
		}

	}
	public void addParameter(Parameter p){
		theMethod.addParameter(p);
	}
	public void quit(){
		this.dispose();
	}
	public void submit(){
		String name = nameField.getText();
		if(name.equals("")==true){ 
			Util.showError(this, "Name cannot be blank"); 
			return; 
		} 
		name = name.substring(0,1).toLowerCase()+name.substring(1);
		if(name.equals(nameField.getText())==false){
			Util.showError(this, "Must start with lowercase");
			return;
		}
		name = name.trim().replaceAll(" +", "");
		if(name.equals(nameField.getText())==false){
			Util.showError(this, "Must not contain white spaces");
			return;
		}
		name = name.replaceAll("[^A-Za-z]", "");
		if(name.equals(nameField.getText())==false){
			Util.showError(this, "Name must only be alphanumeric");
			return;
		}
		theMethod.setName(nameField.getText());
		theMethod.setType((String)typeBox.getSelectedItem());
		methodFrame.addMethod(theMethod);
		methodFrame.rebuildList();
		quit();
	}
	/**
	 * Rebuilds the list of parameters
	 */
	public void rebuildList(){
		parameterBox.removeAllItems();
		if(theMethod!=null){
			String[] param = theMethod.getParameterList();
			for(int i = 0; i<param.length; i++){
				parameterBox.addItem(param[i]);
			}
		}
	}
}
